#include "../logs/log.h"
#include <vector>
#include <thread>
#include <chrono>
void bench(std::string logger_name,size_t thr_count,size_t msg_count,size_t msg_len)
{
    // 获取日志器
    bitlog::Logger::ptr logger = bitlog::getLogger(logger_name);
    if(logger.get() == nullptr)
    {
        return;
    }
    std::cout << "测试日志：" << msg_count << "条,总大小：" << msg_count * msg_len / 1024 << "KB\n";
    // 组织指定长度的日志消息
    std::string msg(msg_len - 1, 'A'); // 给末尾添加换行
    // 创建指定数量的日志线程
    std::vector<std::thread> threads;
    std::vector<double> cost_array(thr_count);
    size_t msg_per_thr = msg_count / thr_count; // 平均每个线程输出日志数量
    for(int i = 0; i < thr_count; i++)
    {
        threads.emplace_back([&,i](){
            // 线程函数内部开始计时
            auto start = std::chrono::high_resolution_clock::now();
            // 创建循环写日志
            for(int j = 0; j < msg_per_thr; j++)
            {
                logger->fatal("%s",msg.c_str());
            }
            // 线程函数内部结束计时
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost = end - start;
            cost_array[i] = cost.count();
            std::cout << "\t线程" << i << ":" << "\t输出日志数量：" << msg_per_thr <<
                 ",耗时：" << cost.count() << "s" << std::endl;
        }); // 可以避免拷贝构造
    }
    // 等待线程退出
    for(int i = 0; i < thr_count; i++)
    {
        threads[i].join();
    }

    // 计算总耗时 ！！！在多线程中 每个线程都会消耗时间 但是线程是并发处理的 因此耗时最高的就说总时间 并非所有相加
    double max_cost = cost_array[0];
    for(int i = 1; i < thr_count; i++)
    {
       max_cost =  max_cost < cost_array[i] ? cost_array[i] : max_cost;
    }
    size_t msg_per_sec = msg_count / max_cost;
    size_t size_per_sec = (msg_count * msg_len) / (max_cost * 1024);
    // 输出打印
    std::cout << "\t总耗时：" << max_cost << "s\n";
    std::cout << "\t每秒输出日志数量：" << msg_per_sec << "条\n";
    std::cout << "\t每秒输出日志大熊：" << size_per_sec << "KB\n";
}

void async_bench()
{
    std::unique_ptr<bitlog::LoggerBuilder> builder(new bitlog::GlobalLoggerBuilder()); 
    builder->buildLoggerName("async_logger");
    builder->buildFormatter("%m%n");
    builder->buildLoggerType(bitlog::LoggerType::LOGGER_ASYNC);
    builder->buildEnableUnSafeAsync(); // 开启非安全模式--为了将实际落地时间排除在外 在内存写完就结束计时
    builder->buildSink<bitlog::FileSink>("./logfile/async.log");
    builder->build();
    bench("async_logger",10,1000000,100);
    
}
void sync_bench()
{
    std::unique_ptr<bitlog::LoggerBuilder> builder(new bitlog::GlobalLoggerBuilder()); 
    builder->buildLoggerName("sync_logger");
    builder->buildFormatter("%m%n");
    builder->buildLoggerType(bitlog::LoggerType::LOGGER_SYNC);
    builder->buildSink<bitlog::FileSink>("./logfile/sync.log");
    builder->build();
    bench("sync_logger",1,1000000,100);
    
}
int main()
{
    async_bench();
    return 0;
}